/*	$Id: log.h 472 2007-08-15 04:20:09Z phrakt $	*/
/*
 * Copyright (c) 2003 Jean-Francois Brousseau <phrakt@gmail.com>
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#ifndef _CANOPY_LOG_H_
#define _CANOPY_LOG_H_

#include <sys/types.h>

#include <stdarg.h>

/* logging priority levels */
enum cnp_log_pri {
	CNP_LOG_DEBUG,
	CNP_LOG_INFO,
	CNP_LOG_NOTICE,
	CNP_LOG_WARN,
	CNP_LOG_WARNING = CNP_LOG_WARN,
	CNP_LOG_ERR,
	CNP_LOG_ERROR = CNP_LOG_ERR,
	CNP_LOG_ERRNO,
	CNP_LOG_CRIT
};




typedef struct cnp_log_chan  cnp_log_t;
typedef int                  cnp_logmask_t;


/*
 * The following macros are used to manipulate log masks.  A mask is just a
 * bit-field, starting with the LSB at index 0.  If the bit whose index is
 * equal to a priority level's integer value is set to 1, messages with that
 * priority level will be blocked.
 *
 * CNP_LOG_CLRMASK() clears the log mask <m>.  No priority levels are blocked
 * when a mask is clear.
 *
 * CNP_LOG_MASKALL() fills the log mask <m>.  A full mask blocks all priority
 * levels.
 *
 * CNP_LOG_MASKPRI() masks the priority level <l> in the log mask <m>.
 *
 * CNP_LOG_UNMASKPRI() unmasks the priority level <l> in the log mask <m>.
 *
 * CNP_LOG_ISMASKED() can be used to test whether the priority level <l> is
 * masked in the log mask <m>.
 *
 */
#define CNP_LOG_CLRMASK(m)	(m = 0)
#define CNP_LOG_MASKALL(m)	(m = ~0)
#define CNP_LOG_MASKPRI(m, l)	(m |= (1 << l))
#define CNP_LOG_UNMASKPRI(m, l)	(m &= ~(1 << l))
#define CNP_LOG_ISMASKED(m, l)	(m & (1 << l))



/*
 * The cnp_log_msg structure is used to dispatch a log message to the
 * handlers that are registered for that channel.  The <msg_string> field
 * is a dynamically-allocated string containing the formatted message itself.
 * The <msg_priority> field specifies the level of priority that was
 * attached to the message.  Each message is timestamped and the value is
 * kept in the <msg_time> field.  The <msg_chan> field is a back-pointer to
 * the channel on which the log message was written.
 */

struct cnp_log_msg {
	char            *msg_string;
	int              msg_priority;
	struct timeval   msg_time;
	cnp_log_t       *msg_chan;
};



/* logging facility */
int         cnp_log_init    (void);
cnp_log_t*  cnp_log_open    (const char *, int);
void        cnp_log_getmask (cnp_log_t *, cnp_logmask_t *);
void        cnp_log_setmask (cnp_log_t *, cnp_logmask_t);
void        cnp_log_close   (cnp_log_t *);
int         cnp_log_addhdlr (cnp_log_t *, cnp_logmask_t,
				void (*)(struct cnp_log_msg *, void *), void *);
int         cnp_log_rmhdlr  (cnp_log_t *, void (*)(struct cnp_log_msg *,
				void *)); 

void        cnp_log     (cnp_log_t *, enum cnp_log_pri, const char *, ...);
void        cnp_vlog    (cnp_log_t *, enum cnp_log_pri, const char *, va_list);


#endif /* _CANOPY_LOG_H_ */
